#pragma once

#include "ISimulatorControl.h"

class SimulatorControl : public ISimulatorControl
{
public:
	SimulatorControl(void);
	~SimulatorControl(void);

	int getSensorValue(int port);
	void setSensorMode(int port, bool active);

	void setLightBrightness(int port, int level);
	void setLightStatus(int port, bool on);

	int getBatteryValue();
	int getKeyStatus(int keys, bool isPressed);
	
	unsigned long registKeyDelegator(ISimulatorControl::TaskDelegator fp);

	void sendMessage(unsigned char msg);
	unsigned char receiveMessage(bool untilBlock);
	void clearMessage();
	int registMessageDelegator(ISimulatorControl::TaskDelegator fp);

	void orderMotor(int port, char* methodName, int param=-1);

	void cputcLCD(ISimulatorControl::LCD_DISPLAY_MODE mode, char c, int pos);
	void cputwLCD(unsigned word);
	void cputsLCD(char* s);
	void clearLCD();

	void play(unsigned char pitch, unsigned char length);
	void setSoundDuration(unsigned int len);
	void setSoundInternote(unsigned int len);
	void stopSound();
	void beepSound();
	void notifyLoopCount(unsigned int count);

	void setSensorName(int port, char* name);
	void setMotorName(int port, char* name);
	char* getSensorName(int port);
	char* getMotorName(int port);


	/**
	 * Methods for Simulator side
	 */
	void SetKeyStatusToRobot(bool onoff, bool run, bool view, bool prog);
	void SendMessageToRobot(unsigned char msg);
	void SetSensorValue(int port, int value);
	void SetBatteryLevel(int level);

	typedef void (*SetSensorModeFp)(int port, bool active);
	typedef void (*SetLightBrightnessFp)(int port, int level);
	typedef void (*SetLightStatusFp)(int port, bool on);
	typedef void (*SendMessageFp)(unsigned char msg);
	typedef unsigned char (*ReceiveMessageFp)(bool untilBlock);
	typedef void (*ClearMessageFp)(void);
	typedef void (*OrderMotorFp)(int port, char* methodName, int param);
	typedef void (*CputCLCDFp)(int mode, char c, int pos);
	typedef void (*CputWLCDFp)(unsigned word);
	typedef void (*CputSLCDFp)(char* s);
	typedef void (*ClearLCDFp)(void);
	typedef void (*PlayFp)(unsigned char pitch, unsigned char length);
	typedef void (*SetSoundDurationFp)(unsigned int len);
	typedef void (*SetSoundInternoteFp)(unsigned int len);
	typedef void (*StopSoundFp)(void);
	typedef void (*BeepSoundFp)(void);
	typedef void (*NotifyLoopCountFp)(unsigned int count);

	void SetDelegatorSetSensorModeFp(SetSensorModeFp fp);
	void SetDelegatorSetLightBrightnessFp(SetLightBrightnessFp fp);
	void SetDelegatorSetLightStatusFp(SetLightStatusFp fp);
	void SetDelegatorSendMessageFp(SendMessageFp fp);
	void SetDelegatorReceiveMessageFp(ReceiveMessageFp fp);
	void SetDelegatorClearMessageFp(ClearMessageFp fp);
	void SetDelegatorOrderMotorFp(OrderMotorFp fp);
	void SetDelegatorCputCLCDFp(CputCLCDFp fp);
	void SetDelegatorCputWLCDFp(CputWLCDFp fp);
	void SetDelegatorCputSLCDFp(CputSLCDFp fp);
	void SetDelegatorClearLCDFp(ClearLCDFp fp);
	void SetDelegatorPlayFp(PlayFp fp);
	void SetDelegatorSetSoundDurationFp(SetSoundDurationFp fp);
	void SetDelegatorSetSoundInternoteFp(SetSoundInternoteFp fp);
	void SetDelegatorStopSoundFp(StopSoundFp fp);
	void SetDelegatorBeepSoundFp(BeepSoundFp fp);
	void SetDelegatorNotifyLoopCount(NotifyLoopCountFp fp);

private:
	SetSensorModeFp setSensorModeFp;
	SetLightBrightnessFp setLightBrightnessFp;
	SetLightStatusFp setLightStatusFp;
	SendMessageFp sendMessageFp;
	ReceiveMessageFp receiveMessageFp;
	ClearMessageFp clearMessageFp;
	OrderMotorFp orderMotorFp;
	CputCLCDFp cputCLCDFp;
	CputWLCDFp cputWLCDFp;
	CputSLCDFp cputSLCDFp;
	ClearLCDFp clearLCDFp;
	PlayFp playFp;
	SetSoundDurationFp setSoundDurationFp;
	SetSoundInternoteFp setSoundInternoteFp;
	StopSoundFp stopSoundFp;
	BeepSoundFp beepSoundFp;
	NotifyLoopCountFp notifyLoopCountFp;

	ISimulatorControl::TaskDelegator keyTaskDelegator;
	ISimulatorControl::TaskDelegator msgTaskDelegator;

	int keyStatus;
	int batteryLevel;
	int sensorValue[3];

	char* motorName[3];
	char* sensorName[3];

	static int nameLenMax;
	static int portNumMax;

};
